﻿using FluentValidation;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using ValidationResult = System.Windows.Controls.ValidationResult;

namespace YY.Admin.Core.FluentValidation
{
    internal class FluentAutoValidationRule<T> : ValidationRule, IFluentAutoValidationRule where T : class
    {
        public IValidator<T>? Validator { get; set; }

        /// <summary>
        /// 当前绑定控件对应的属性名
        /// </summary>
        public string? PropertyName { get; set; }

        // 👇 ValidationStep.UpdatedValue为true: 让Validate方法中value参数为BindingExpression类型，而非值类型
        public FluentAutoValidationRule() : base(ValidationStep.UpdatedValue, true) { }

        public override ValidationResult Validate(object value, CultureInfo cultureInfo)
        {
            if (Validator == null || string.IsNullOrEmpty(PropertyName))
                return ValidationResult.ValidResult;

            // 如果 value 不是 BindingExpression，先尝试判断是否是 BindingGroup (兼容性保护)
            if (value is not BindingExpression bindingExpr)
            {
                // 有时 WPF 在不同阶段会传入 BindingGroup 或其他类型，直接跳过初始化阶段的验证，避免误报
                return ValidationResult.ValidResult;
            }

            // --- 更可靠地判断“初始化阶段的第一次验证” ---
            // 如果绑定目标尚未挂到视觉树或控件未 Loaded，则视为初始化，不执行验证
            var target = bindingExpr.Target as DependencyObject;
            if (target != null)
            {
                // 1) 如果是 FrameworkElement 并且还没 Loaded，则跳过
                if (target is FrameworkElement fe && !fe.IsLoaded)
                    return ValidationResult.ValidResult;

                // 2) 如果 PresentationSource 为空，也说明还没连接到可视树，跳过
                var ps = System.Windows.PresentationSource.FromVisual(target as System.Windows.Media.Visual);
                if (ps == null)
                    return ValidationResult.ValidResult;

                // 3) 另外，如果控件不可见，也可能是初始化阶段，可根据需要跳过
                if (target is UIElement ui && !ui.IsVisible)
                    return ValidationResult.ValidResult;
            }

            var dataItem = bindingExpr.DataItem;
            if (dataItem == null)
                return new ValidationResult(false, "绑定源为空");

            // 解析 Path，例如 "SysUser.Account"
            var path = bindingExpr.ParentBinding.Path?.Path ?? string.Empty;
            var rootPropName = path.Split('.')[0]; // SysUser
            var modelProp = dataItem.GetType().GetProperty(rootPropName);
            if (modelProp == null)
                return ValidationResult.ValidResult;

            var modelObj = modelProp.GetValue(dataItem);
            if (modelObj is not T model)
                return ValidationResult.ValidResult;

            // 调用 FluentValidation 验证指定属性
            var result = Validator.ValidateAsync(model, opts => opts.IncludeProperties(PropertyName))
                .ConfigureAwait(false) // 同步等待Task（ValidationRule 不支持 async → 只能同步等待。）
                .GetAwaiter()
                .GetResult();
            var error = result.Errors.FirstOrDefault(e => e.PropertyName == PropertyName);

            if (error != null)
                return new ValidationResult(false, error.ErrorMessage);

            return ValidationResult.ValidResult;

        }
    }
}
